package us.versus.them.bitly;

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.text.TextField;

import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;

class App {

	var w : Int;
	var h : Int;
	var bitmap : Bitmap;

	var bitmapData : BitmapData;
	var bitmapData1 : BitmapData;
	var bitmapData2 : BitmapData;

	var sum : Float;
	var mask : Array< Array< Float > >;

	var busy : Bool; // poor man's sentinel

	var current:Bitter;
	var bitters:Hash< Bitter >;

	public function new() {
		var root = flash.Lib.current;
		this.w = Math.floor( root.stage.stageWidth  );
		this.h = Math.floor( root.stage.stageHeight );

		this.bitmapData1 = new BitmapData( w, h );
		this.bitmapData2 = new BitmapData( w, h );
		this.bitmapData = this.bitmapData1;
		this.bitmap = new Bitmap();

		bitters = new Hash< Bitter >();
		bitters.set( '49', new Pavg() );
		bitters.set( '50', new Cloud() );
		bitters.set( '51', new Hough() );
		bitters.set( '52', new Bumpin() );
		current = bitters.get( '49' );

		root.addChild( this.bitmap );

		reset();

		flash.Lib.current.addEventListener( Event.ENTER_FRAME, loop );
		flash.Lib.current.stage.addEventListener( KeyboardEvent.KEY_DOWN, keyDown );
		flash.Lib.current.stage.addEventListener( MouseEvent.MOUSE_DOWN, mouseDown );
	}

	public function mouseDown( _ ) {
		reset();
	}

	public function keyDown( e:KeyboardEvent ) {
		var tmp = bitters.get( '' + e.charCode );
		if ( null != tmp ) {
			current = tmp;
			reset();
		} else {
			switch( e.charCode ) {
				default: 
					reset();
					//trace( e.charCode );
			}
		}
	}

	public function reset() {
		if ( busy ) return;
		busy = true;

		this.bitmapData = this.bitmapData1;
		this.bitmap.bitmapData = this.bitmapData;
		current.reset( w, h, bitmapData, bitmapData2 );

		busy = false;
	}

	public function loop( _ ) {
		if ( !busy ) {
			busy = true;

			var tmp = inactive();

			if( current.loop( w, h, bitmapData, tmp ) ) {
				flip( tmp );
			}

			busy = false;
		}
	}

	public function inactive() { 
		return (
			if ( this.bitmapData == this.bitmapData1 ) {
				this.bitmapData2;
			} else { 
				this.bitmapData1;
			}
	   );
	}

	public static inline function pixelAt( x,y,w,h,bitmapData ) {
		if ( -1 == x ) x = w - 1; else
		if ( w == x ) x = 0;
		if ( -1 == y ) y = h - 1; else
		if ( h == y ) y = 0;
		return bitmapData.getPixel( x, y );
	}

	public function flip( tmp ) {
		// make the inactive bitmapData active
		this.bitmapData = tmp;
		this.bitmap.bitmapData = bitmapData;
	}

	public static inline function rgb( r:Float, g:Float, b:Float ) : Int {
		return Math.floor( 0
			| ( Math.floor( r ) << 16 )
			| ( Math.floor( g ) << 8 )
			| Math.floor( b )
		);
	}

	public static inline function clear( w:Int, h:Int, bitmapData:BitmapData, ?color:Int ) : Void {
		if ( null == color ) {
			color = 0;
		}
		for ( x in 0 ... w ) {
			for ( y in 0 ... h ) {
				bitmapData.setPixel( x, y, color );
			}
		}
	}

}
